package org.cosmocalc;

import java.awt.*;
import java.awt.event.*;

public class CosmoDisplay extends Frame implements WindowListener, ActionListener {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 5713300299360883534L;
	private Button calc;
	private Button dlGraph;
	private Button daGraph;
	private Button ageGraph;
	private Button lbGraph;
	private Label bText;
	private TextField om;
	private TextField ol;
	private TextField hu;
	private TextField redshift;
	private TextField lumdist;
	private TextField angdist;
	private TextField age;
	private TextField lookback;
	private CosmoCalculator cosmoCalc;
	private CosmoGraph theCosmoGraph;

	public void init() {
		setLayout(new GridLayout(4,1));
		
		Panel p = new Panel();
		p.setLayout(new GridLayout(4, 2));
		p.add(new Label(" Matter density:"));
		this.om = new TextField("0.3", 5);
		p.add(this.om);
		p.add(new Label(" Cosmological constant:"));
		this.ol = new TextField("0.7", 5);
		p.add(this.ol);
		p.add(new Label(" Hubble constant:"));
		this.hu = new TextField("0.7", 5);
		p.add(this.hu);
		p.add(new Label(" Redshift"));
		this.redshift = new TextField("2.0", 5);
		p.add(this.redshift);
		add(p);
		
		p = new Panel();
		p.setLayout(new GridLayout(3, 2));
		p.add(new Label(" "));
		p.add(new Label(" "));
		p.add(new Label(" "));
		p.add(new Label(" "));
		calc = new Button("Calculate");
		p.add(new Label(" "));
		p.add(calc);
		add(p);
		
		p = new Panel();
		p.setLayout(new GridLayout(4,2));
		p.add(new Label(" Luminosity distance:"));
		this.lumdist = new TextField(15);
		p.add(this.lumdist);
		p.add(new Label(" Angular distance:"));
		this.angdist = new TextField(15);
		p.add(this.angdist);
		p.add(new Label(" Time since Big Bang:"));
		this.age = new TextField(15);
		p.add(this.age);
		p.add(new Label(" Lookback time:"));
		this.lookback = new TextField(15);
		p.add(this.lookback);
		add(p);
		
		p = new Panel();
		p.setLayout(new GridLayout(3,2));
		p.add(new Label(" "));
		bText = new Label(" ");
		p.add(bText);
		dlGraph = new Button("Luminosity distance graph");
		p.add(dlGraph);
		daGraph = new Button("Angular distance graph");
		p.add(daGraph);
		ageGraph = new Button("Age graph");
		p.add(ageGraph);
		lbGraph = new Button("Lookback time graph");
		p.add(lbGraph);
		add(p);

		addWindowListener(this);
		calc.addActionListener(this);
		dlGraph.addActionListener(this);
		daGraph.addActionListener(this);
		ageGraph.addActionListener(this);
		lbGraph.addActionListener(this);
		
		cosmoCalc = new CosmoCalculator();
		theCosmoGraph = new CosmoGraph("");
	}
	
	public void readCosmoFields(CosmoCalculator cosmoCalc) {
		double om, ol, hu;
		om = Double.valueOf(this.om.getText()).doubleValue();
		ol = Double.valueOf(this.ol.getText()).doubleValue();
		hu = Double.valueOf(this.hu.getText()).doubleValue();
		cosmoCalc.setCosmo(om, ol, hu);		
	}

	public void updateFields(CosmoCalculator cosmoCalc) {
		double z, lumdist, angdist, time, lookback, ageOfU;

		this.lumdist .setText("Calculating...");
		this.angdist .setText("Calculating...");
		this.age     .setText("Calculating...");
		this.lookback.setText("Calculating...");
		
		this.readCosmoFields(cosmoCalc);

		z = Double.valueOf(this.redshift.getText()).doubleValue();		
		if (z < 0.) {
			z = 0.;
			this.redshift.setText("" + 0.);
		}
		
		lumdist  = cosmoCalc.lumDist     (z);
		angdist  = cosmoCalc.angDist     (z);
		time     = cosmoCalc.time        (z);
		lookback = cosmoCalc.lookbackTime(z);
		ageOfU   = time + lookback;
		
		lumdist  = Math.round(lumdist *100.)/100.;
		angdist  = Math.round(angdist *100.)/100.;
		time     = Math.round(time    *100.)/100.;
		lookback = Math.round(lookback*100.)/100.;
		
		this.lumdist .setText(lumdist + " Gpc");
		this.angdist .setText(angdist + " kpc per arcsec");
		this.age     .setText(time + " Gyrs (" + Math.round(time/ageOfU*1000.)/10. + "%)");
		this.lookback.setText(lookback + " Gyrs (" + Math.round(lookback/ageOfU*1000.)/10. + "%)");
	}

	public void actionPerformed(ActionEvent event) {
		bText.setText("   Calculating...");
		if (event.getActionCommand().contentEquals("Calculate")) updateFields(this.cosmoCalc);
		else {
			this.readCosmoFields(cosmoCalc);
			theCosmoGraph = new CosmoGraph(event.getActionCommand().toString());
			if (event.getActionCommand().contentEquals("Luminosity distance graph")) {
				theCosmoGraph.dlGraph(cosmoCalc);
			}
			else if (event.getActionCommand().contentEquals("Angular distance graph")) {
				theCosmoGraph.daGraph(cosmoCalc);
			}
			else if (event.getActionCommand().contentEquals("Age graph")) {
				theCosmoGraph.ageGraph(cosmoCalc);
			}
			else if (event.getActionCommand().contentEquals("Lookback time graph")) {
				theCosmoGraph.lbGraph(cosmoCalc);
			}
			else System.out.println("Error!!");
		}
		bText.setText(" ");
		return;
	}
		
	public void windowOpened(WindowEvent event) {
		// TODO Auto-generated method stub
		
	}

	public void windowClosing(WindowEvent event) {
		Window theWindow = event.getWindow();
		theWindow.dispose();
	}

	public void windowClosed(WindowEvent event) {
		System.exit(0);
	}

	public void windowIconified(WindowEvent event) {
		// TODO Auto-generated method stub
		
	}

	public void windowDeiconified(WindowEvent event) {
		// TODO Auto-generated method stub
		
	}

	public void windowActivated(WindowEvent event) {
		// TODO Auto-generated method stub
		
	}

	public void windowDeactivated(WindowEvent event) {
		// TODO Auto-generated method stub
		
	}
	
	public static void main(String[] args) {
		
		CosmoDisplay ex = new CosmoDisplay();
		
		ex.setTitle("Cosmological Calculator");
		ex.init();
		ex.pack();
		ex.setVisible(true);
	}
}
